﻿using System;
using System.Data;
using System.Data.Objects;
using RedRiver.Framework.XtraCommon.FormHelper;

namespace RedRiver.Framework.XtraCommon.Templates.Generic{
    public class EntityDataGridViewForm : DataGridViewForm{

        /// <summary>
        /// 初始化 数据上下文默认方法
        /// </summary>
        /// <typeparam name="TContext"></typeparam>
        /// <typeparam name="TModel"></typeparam>
        protected EntityDataContext<TContext> InitDataContext<TContext, TModel>()
            where TContext : ObjectContext, new() where TModel : class {
            return InitDataContext<TContext, TModel>(new TContext());
        }

        /// <summary>
        /// 初始化 数据上下文默认方法
        /// </summary>
        /// <typeparam name="TContext"></typeparam>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="context"></param>
        protected EntityDataContext<TContext> InitDataContext<TContext, TModel>(TContext context)
            where TContext : ObjectContext
            where TModel : class {
            return InitDataContext<TContext,TModel>(new EntityDataContext<TContext>(context));
        }

        /// <summary>
        /// 初始化 数据上下文默认方法
        /// </summary>
        /// <typeparam name="TContext"></typeparam>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="context"></param>
        protected EntityDataContext<TContext> InitDataContext<TContext, TModel>(EntityDataContext<TContext> context)
            where TContext : ObjectContext
            where TModel : class {
            DataContext = context;
            context.OnRefreshData = d => d.Refresh(RefreshMode.StoreWins, DefaultBindingSource);
            context.OnLoadData = d =>{
                                     DefaultBindingSource.DataSource = null;
                                     DefaultBindingSource.DataSource = d.CreateObjectSet<TModel>();
                                 };
            context.OnUpdateData = d => {
                try {
                    d.SaveChanges();
                } catch (OptimisticConcurrencyException) {
                    d.Refresh(RefreshMode.ClientWins, defaultBindingSource);
                    d.SaveChanges();
                }};
            return context;
        }

        /// <summary>
        /// 实体数据上下文
        /// </summary>
        public virtual IEntityDataContext DataContext{
            get;
            set;
        }

        protected override bool IsDataSourceChanged(System.Windows.Forms.BindingSource bindSource){
            if(DataContext!=null){
                return DataContext.HasEntityChanged;    
            }
            return false;
        }

        protected override void OnLoadData(){
            base.OnLoadData();
            if (DataContext != null){
                if (InvokeRequired){
                    BeginInvoke(new Action(DataContext.LoadData));
                } else{
                    DataContext.LoadData();
                }
            }
        }

        protected override void OnUpdateData(){
            base.OnUpdateData();
            if (DataContext != null){
                if (InvokeRequired){
                    BeginInvoke(new Action(DataContext.UpdateData));
                } else{
                    DataContext.UpdateData();
                }
            }
        }

        public override void OnRefreshData(){
            if (DataContext != null){
                if (InvokeRequired){
                    BeginInvoke(new Action(DataContext.RefreshData));
                } else{
                    DataContext.RefreshData();
                }
            }
        }

        protected override void OnEditFormClosed(DetailEditForm editForm) {
            DataContext.Context.Refresh(RefreshMode.StoreWins, editForm.DefaultBindingSource);
        }

        protected override void OnAddFormClosed(DetailEditForm editForm){
            if (editForm.IsDataChanged) {
                for (int i = editForm.DefaultBindingSource.Count - 1; i >= 0; i--) {
                    object item = editForm.DefaultBindingSource[i];
                    ((EntityDetailEditForm)editForm).DataContext.Context.Detach(item);
                    DefaultBindingSource.Position = DefaultBindingSource.Add(item);
                    DataContext.Context.AcceptAllChanges();
                }
            }
        }
    }
}